package com.haibara.codesubmiteval.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.haibara.codesubmiteval.annotation.AuthCheck;
import com.haibara.codesubmiteval.common.BaseResponse;
import com.haibara.codesubmiteval.common.BatchDeleteRequest;
import com.haibara.codesubmiteval.common.DeleteRequest;
import com.haibara.codesubmiteval.common.ErrorCode;
import com.haibara.codesubmiteval.constant.AuthConstant;
import com.haibara.codesubmiteval.constant.RedisKeyConstant;
import com.haibara.codesubmiteval.context.UserContext;
import com.haibara.codesubmiteval.exception.BusinessException;
import com.haibara.codesubmiteval.exception.ThrowUtils;
import com.haibara.codesubmiteval.model.dto.user.*;
import com.haibara.codesubmiteval.model.entity.User;
import com.haibara.codesubmiteval.model.vo.LoginUserVO;
import com.haibara.codesubmiteval.model.vo.Top10VO;
import com.haibara.codesubmiteval.model.vo.TotalInfo;
import com.haibara.codesubmiteval.model.vo.UserAcceptedQuestionVO;
import com.haibara.codesubmiteval.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 用户接口
 *
 * @Author: mengyu
 * @Date: 2025/2/3
 */
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {

    @Resource
    private UserService userService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 用户登录
     *
     * @param userLoginRequest 用户登录请求
     * @param request          request请求头
     * @return 登录用户视图
     */
    @PostMapping("/login")
    public BaseResponse<LoginUserVO> userLogin(@RequestBody @Valid UserLoginRequest userLoginRequest, HttpServletRequest request, HttpServletResponse response) {
        if (userLoginRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        long id;
        try {
            id = Long.parseLong(userLoginRequest.getId());
        } catch (Exception e) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "学号应该为纯数字");
        }
        String password = userLoginRequest.getPassword();
        LoginUserVO loginUserVO = userService.userLogin(id, password, request, response);
        return BaseResponse.success(loginUserVO);
    }


    /**
     * 用户注销
     *
     * @param request request请求头
     * @return 执行信息
     */
    @PostMapping("/logout")
    public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
        if (request == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.userLogout(request);
        return BaseResponse.success(result);
    }

    /**
     * 获取当前登录用户
     *
     * @param request request请求头
     * @return 登录用户视图
     */
    @GetMapping("/get/login")
    public BaseResponse<LoginUserVO> getLoginUser(HttpServletRequest request) {
        User user = userService.getLoginUser(request);
        return BaseResponse.success(LoginUserVO.getLoginUserVOByUser(user));
    }

    /**
     * 修改密码
     *
     * @param userChangePasswordRequest 修改密码请求
     * @return 执行信息
     */
    @PostMapping("/change")
    @AuthCheck(mustRole = AuthConstant.USER)
    public BaseResponse<Boolean> changePassword(@RequestBody @Valid UserChangePasswordRequest userChangePasswordRequest) {
        userService.changePassword(userChangePasswordRequest);
        return BaseResponse.success(true);
    }

    /**
     * 创建用户
     *
     * @param userAddRequest 新增用户请求
     * @return 用户id
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<Long> addUser(@RequestBody @Valid UserAddRequest userAddRequest) {
        if (userAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Long userId = userService.addUser(userAddRequest);
        return BaseResponse.success(userId);
    }

    /**
     * 根据文件批量新增用户
     *
     * @param file 用户文件
     * @return 新增的用户数
     */
    @PostMapping("/add/file")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<Integer> addUserByFile(@RequestPart("file") MultipartFile file) {
        Integer size = userService.addUserByFile(file);
        return BaseResponse.success(size);
    }

    /**
     * 删除用户
     *
     * @param deleteRequest 删除用户请求
     * @return 执行信息
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        userService.deleteUser(deleteRequest.getId());
        return BaseResponse.success(true);
    }

    /**
     * 批量删除用户
     *
     * @param batchDeleteRequest 删除请求
     * @return 执行信息
     */
    @DeleteMapping("/batchDelete")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<Boolean> batchDeleteUser(@RequestBody @Valid BatchDeleteRequest batchDeleteRequest) {
        boolean b = userService.removeBatchByIds(batchDeleteRequest.getIds());
        ThrowUtils.throwIf(!b, ErrorCode.SYSTEM_ERROR, "删除用户失败 : " + batchDeleteRequest.getIds());
        return BaseResponse.success(true);
    }

    /**
     * 更新用户
     *
     * @param userUpdateRequest 用户更新请求
     * @return 执行信息
     */
    @PostMapping("/update")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<Boolean> updateUser(@RequestBody @Valid UserUpdateRequest userUpdateRequest) {
        userService.updateUser(userUpdateRequest);
        return BaseResponse.success(true);
    }

    /**
     * 根据 id 获取用户（仅管理员）
     *
     * @param id 用户id
     * @return 用户信息
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<User> getUserById(Long id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR);
        return BaseResponse.success(user);
    }

    /**
     * 分页获取用户列表（仅管理员）
     *
     * @param userQueryRequest 用户分页查询请求
     * @return 用户分页信息
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = AuthConstant.ADMIN)
    public BaseResponse<Page<User>> pageQueryUser(@RequestBody UserQueryRequest userQueryRequest) {
        return BaseResponse.success(userService.pageQueryUser(userQueryRequest));
    }

    /**
     * 获取用户题目完成信息，包括完成题目数和题目总数
     *
     * @return 用户题目完成信息
     */
    @GetMapping("/completion")
    @AuthCheck(mustRole = AuthConstant.USER)
    public BaseResponse<UserAcceptedQuestionVO> getUserCompletionOfTheQuestion() {
        Long userId = UserContext.get().getId();
        UserAcceptedQuestionVO result = userService.getUserCompletionOfTheQuestion(userId);
        return BaseResponse.success(result);
    }

    /**
     * 获取系统题目完成数整体信息
     *
     * @return 系统题目完整信息
     */
    @GetMapping("/total")
    public BaseResponse<TotalInfo> getTotalInfo() {
        TotalInfo result = userService.getTotalInfo();
        return BaseResponse.success(result);
    }

    /**
     * 获取系统总分用户Top10
     *
     * @return Top10
     */
    @GetMapping("/top10")
    public BaseResponse<List<Top10VO>> getTop10Ranking() {
        List<Top10VO> result = userService.getTop10Ranking();
        return BaseResponse.success(result);
    }

    /**
     * 获取当前用户排名
     *
     * @return 排名信息
     */
    @GetMapping("/myRank")
    @AuthCheck(mustRole = AuthConstant.USER)
    public BaseResponse<Top10VO> getMyRank() {
        Long userId = UserContext.get().getId();
        Top10VO result = userService.getMyRank(userId);
        return BaseResponse.success(result);
    }

    /**
     * 获取当前用户的完成题目id
     *
     * @return 完成题目id
     */
    @GetMapping("/myAcceptedQuestion")
    @AuthCheck(mustRole = AuthConstant.USER)
    public BaseResponse<List<Long>> getMyAcceptedQuestion() {
        Long userId = UserContext.get().getId();
        List<Long> result = userService.getMyAcceptedQuestion(userId);
        return BaseResponse.success(result);
    }
}
